package dao

import (
	"database/sql"
	"goseckill/common"
	"goseckill/models"
	"log"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

type IOrderDao interface {
	Conn() error
	Insert(*models.Order) (int64, error)
	Delete(int64) bool
	Update(*models.Order) error
	SelectByKey(int64) (*models.Order, error)
	SelectAll() ([]*models.Order, error)
	SelectAllWithInfo() (map[int]map[string]string, error)
}

// 接口的实现类
type OrderManager struct{
	table string
	conn *gorm.DB
}

func NewOrderDao(table  string, db *sql.DB) IOrderDao {
	gormDB,err  :=gorm.Open(mysql.New(mysql.Config{
		Conn: db,
	}), &gorm.Config{})  // 根据现有数据库连接创建
	if err!=nil {log.Fatal(err)}

	return &OrderManager{table: table,conn: gormDB}
}
// 实现具体的方法

func (o *OrderManager) Conn() error {
	if o.conn == nil {
		// 建立新的连接
		conn,err := common.NewGormMysqlConn()
		if err!=nil {return err}
		o.conn = conn
	}
	if o.table == "" {
		o.table = "orders"
	}
	return nil
}
func (o *OrderManager) Insert(order *models.Order) (orderID int64, err error) {
	if err = o.Conn();err!=nil {
		return 
	}
	err = o.conn.Create(order).Error
	return order.ID,err
}


func (o *OrderManager)Delete(orderID int64) (isOK bool) {
	if err := o.Conn();err!=nil {
		return 
	}
	err := o.conn.Delete(&models.Order{ID: orderID}).Error
	return err==nil
}
func (o *OrderManager)Update(order *models.Order) (err error) {
	if err = o.Conn();err!=nil {
		return 
	}
	err =  o.conn.Save(order).Error
	return 
}
func (o *OrderManager)SelectByKey(orderID int64) (order *models.Order, err error){
	if errConn := o.Conn();errConn!=nil {
		return &models.Order{},errConn
	}
	// 根据字段查询
	err = o.conn.First(order, orderID).Error
	return 
}
func(o *OrderManager) SelectAll() (orders []*models.Order, err error){
	// select *
	if errConn:= o.Conn();errConn!=nil{
		return nil,errConn
	}
	err = o.conn.Find(orders).Error
	return 
}
func (o *OrderManager)SelectAllWithInfo() (orderMap map[int]map[string]string,err  error){
	if errConn:= o.Conn();errConn!=nil{
		return nil,errConn
	}

	// Select 
	// 	o.ID,p.productName,o.orderStatus 
	// From mall.order as o left join product as p on o.productID=p.ID
	// raw sql
	// sql := "Select o.ID,p.productName,o.orderStatus From mall.order as o left join product as p on o.productID=p.ID"
	// rows,err  := o.conn.Exec(sql).Rows()
	// defer rows.Close()
	// orderMap = GetResultRows(rows)

	err = o.conn.Model(&models.Order{}).Select("orders.product_id").Joins("left join product as p on orders.productID=p.ID").Scan(&orderMap).Error
	return 
}

// GetResultRows 获取所有
func GetResultRows(rows *sql.Rows) map[int]map[string]string {
	//返回所有列
	columns, _ := rows.Columns()
	//这里表示一行所有列的值，用[]byte表示
	values := make([][]byte, len(columns))
	//这里表示一行填充数据
	scans := make([]interface{}, len(columns))
	//这里scans引用vals，把数据填充到[]byte里
	for k := range values {
		scans[k] = &values[k]
	}
	i := 0
	result := make(map[int]map[string]string)
	for rows.Next() {
		//填充数据
		rows.Scan(scans...)
		//每行数据
		row := make(map[string]string)
		//把values中的数据复制到row中
		for k, v := range values {
			key := columns[k]
			//这里把[]byte数据转成string
			row[key] = string(v)
		}
		//放入结果集
		result[i] = row
		i++
	}
	return result
}